package cn.mrcode.fd.plugin.security.realm;

import cn.mrcode.fd.plugin.security.SmartSecurity;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.HashSet;
import java.util.Set;

/**
 * @author zhuqiang
 * @version V1.0
 * @date 2015/11/16 20:55
 */
public class SmartCustomRealm extends AuthorizingRealm {

    private final SmartSecurity smartSecurity;

    public SmartCustomRealm(SmartSecurity smartSecurity) {
        this.smartSecurity = smartSecurity;
//        super.setName(SecurityConstant.REALMS_CUSTOM);
        super.setCredentialsMatcher(new Md5CredentialsMatcher()); //使用自己的md5加密算法
    }

    /**
     * 用于认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        if (token == null) {
            throw new AuthenticationException("参数 token 非法！");
        }

        //获取从表单中提交过来的用户名
        String username = ((UsernamePasswordToken) token).getUsername();
        //通过用户名获取数据库中存储的密码
        String password = smartSecurity.getPassword(username);

        //把用户名和密码放入AuthenticationInfo中以便后续验证操作
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo();
        authenticationInfo.setPrincipals(new SimplePrincipalCollection(username, super.getName()));
        authenticationInfo.setCredentials(password.toCharArray());
        return authenticationInfo;
    }

    /**
     * 授权
     * @param principals
     * @return
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("参数 principals 非法！");
        }

        //获取已认证的用户名
        String username = (String) super.getAvailablePrincipal(principals);
        //获取该用户的权限名称集合
        Set<String> roleNameSet = smartSecurity.getRoleNameSet(username);

        //获取该用户所有的权限集合
        Set<String> permNameSet = new HashSet<String>();
        if (roleNameSet != null && roleNameSet.size() > 0) {
            for (String roleName : roleNameSet) {
                Set<String> currentPermNameSet = smartSecurity.getPermissionNameSet(roleName);
                permNameSet.addAll(currentPermNameSet);
            }
        }

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roleNameSet);
        authorizationInfo.setStringPermissions(permNameSet);
        return authorizationInfo;
    }
}
